package UILayer;
import java.util.ArrayList;

import ControllerLayer.*;
import ModelLayer.*;
/**
 * Class responsible for the ItemUI.
 * 
 * @author Jakob K., Danny P., Anders A.P., Mie P., Anna K. 
 * @version 1.0
 */
public class ItemUI {
    private InputDialog inputDialog;
    private ItemCtr     itemCtr; 

    /**
     * Constructor for objects of class ItemUI
     */
    public ItemUI() {
        inputDialog = new InputDialog();
        itemCtr = new ItemCtr();
    }

    /**
     * Method for creating the menu for itemUI.
     */
    public void startItemUI() {

        boolean goOn = true;
        MenuList<Integer> m2 = new MenuList<Integer>("\fVare menu: ", "\nVælg:");
        m2.addOption("1", "Opret produkt", 1);
        m2.addOption("2", "Opret komposition", 2);
        m2.addOption("3", "Print vareinfo", 3);
        m2.addOption("4", "Opdater vare", 4);
        m2.addOption("5", "Sæt pris", 5);
        m2.addOption("6", "Slet vare", 6);
        m2.addOption("0", "Exit", 0);

        while(goOn) {
            Integer choise = m2.display();
            switch(choise) {
                case 0:
                goOn = false;
                break;
                case 1:
                do{
                    createProduct();
                }
                while (inputDialog.inputBoolean("Ønsker du at tilføje flere produkter?: "));
                break;
                case 2:
                do{
                    createComposition();
                }
                while (inputDialog.inputBoolean("Ønsker du at tilføje flere kompositioner?: "));
                break;
                case 3:
                do{
                    retrieveItem();
                }
                while (inputDialog.inputBoolean("Ønsker du at søge efter flere vare?: "));
                break;
                case 4:
                do{
                    updateItem();
                }
                while(inputDialog.inputBoolean("Ønsker du at opdatere en ny vare?: ")) ;

                break;
                case 5:
                setItemPrice();
                break;

                case 6:
                try {
                    deleteItem();
                }
                catch (Exception e) {
                    deleteItem();
                }
                default:
                System.out.println("Input ikke genkendt");
            }
        }
    }

    /**
     * Sends the information needed to create a product to the ItemCtr object. Uses a do-while loop to check if
     * data is acceptable.
     */
    public void createProduct() {

        inputDialog.displayMessage("Opret produkt: ");
        String name, description;
        int supplierID, quantityInBulk;
        double purchasePrice, size, weight;
        do {
            name = inputDialog.inputString("Angiv navn på produkt: ");
            description = inputDialog.inputString("Lav en beskrivelse af produktet: ");
            supplierID = inputDialog.inputInt("Angiv leverandørnr.: ");
            quantityInBulk = inputDialog.inputInt("Angiv antal i kolli: ");
            purchasePrice = inputDialog.inputDouble("Angiv indkøbspris: ");
            size = inputDialog.inputDouble("Angiv størrelse af produktet i cm^3: ");
            weight = inputDialog.inputDouble("Angiv vægt på produkt i kg: ");
        } while (name == null ||
        description == null ||
        supplierID <= 0 ||
        quantityInBulk <= 0 ||
        purchasePrice <= 0 ||
        size < 0 ||
        weight < 0);
        try {
            itemCtr.createProduct(name, description, supplierID, quantityInBulk, purchasePrice, size, weight);
        } catch (Exception e) {
            System.out.println(e);
        }

    }         

    /**
     * Sends the information needed to create a composition to the ItemCtr object. Uses a do-while loop to check if
     * data is acceptable.
     */
    public void createComposition() {

        inputDialog.displayMessage("Opret komposition: ");
        String name, description;
        do {
            name = inputDialog.inputString("Navnet på varen: ");
            description = inputDialog.inputString("Beskriv varen: ");
        }
        while (name == null ||
        description == null);
        try {
            itemCtr.createComposition(name, description);
        } catch (Exception e) {
            System.out.println(e);
        }
            addProducts();
    }

    /**
     * Method for adding products to a composition.
     */
    private void addProducts() {
        inputDialog.displayMessage("Tilføj produkter til kompositionen: ");
        boolean adding = true;
        while(adding) {
            int id = inputDialog.inputInt("Indtast produktets varenr.: ");
            try {

                if(itemCtr.retrieveItem(id) instanceof Product) {
                    int quantity = validQuantity();
                    itemCtr.addProductToComp((Product)itemCtr.retrieveItem(id), quantity);
                }
                else {
                    System.out.println("Varen er ikke et produkt, prøv igen");
                }
            }
            catch(Exception e) {
                System.out.println(e);
            }
            adding = inputDialog.inputBoolean("Ønskes flere produkter tilføjet?");
        }
    }

    /**
     * Method for validating a quantity input.
     */
    private int validQuantity() {
        int i = 0;
        boolean legit = false;
        while(!legit) {
            i = inputDialog.inputInt("Indtast antal: ");
            if(i <= 0) {
                System.out.println("Input ikke acceptabelt!");
            }
            else {
                legit = true;
            }
        }
        return i;
    }

    /**
     * Method for updating a item of either type product or type composition.
     */
    public void updateItem() {
        try{
            int productID = inputDialog.inputInt("Indtast varenr.: ");
            Item i = itemCtr.retrieveItem(productID);
            String name, description;
            int supplierID, quantityInBulk;
            double purchasePrice, size, weight;
            if (i instanceof Product) {
                Product p = (Product) i;
                do {                
                    name = inputDialog.updateString("navn: ", p.getName());
                    description = inputDialog.updateString("beskrivelse: ", p.getDescription());
                    supplierID = inputDialog.updateInt("leverandørnr.: ", p.getSupplier().getSupplierID());
                    quantityInBulk = inputDialog.updateInt("antal i kolli: ", p.getQuantityInBulk());
                    purchasePrice = inputDialog.updateDouble("indkøbspris: ", p.getPurchasePrice());
                    size = inputDialog.updateDouble("størrelse af produktet i cm^3: ", p.getSize());
                    weight = inputDialog.updateDouble("vægt på produkt i kg: ", p.getWeight());
                } while (name == null ||
                description == null ||
                supplierID <= 0 ||
                quantityInBulk <= 0 ||
                purchasePrice <= 0); 
                itemCtr.updateProduct(productID, name, description, supplierID, quantityInBulk,  purchasePrice, size, weight);            
            }

            if (i instanceof Composition) {
                Composition c = (Composition) i;
                do {

                    name = inputDialog.updateString("navn: ", c.getName());
                    description = inputDialog.updateString("beskrivelse: ", c.getDescription());
                    //purchasePrice = inputDialog.updateDouble("indkøbspris: ", c.getPurchasePrice());
                    //totalPurchasePrice = c.getTotalPurchasePrice();
                } while (name == null ||
                description == null);
                itemCtr.updateComposition(c.getID(), name, description);

                boolean modifying = true;
                MenuList<Integer> m1;

                while(modifying) {
                    m1 = listCompLines(c);
                    Integer choice = m1.display();
                    if(choice > 0 && choice <= c.getCompLines().size()) {
                        modifyLine(c, c.getCompLines().get(choice-1));
                    }
                    else if(choice == 0) {
                        modifying = false;
                    }
                    else if(choice == c.getCompLines().size()+1) {
                        addProducts();
                    }
                    else{
                        System.out.println("Input ikke genkendt");
                    }
                    modifying = inputDialog.inputBoolean("Ønskes flere ændringer?");
                }
            }    
        }
        catch (Exception e) {
            System.out.println(e);
            inputDialog.inputWait();
        }
    }

    /**
     * Method for modifying a specific compositionline inside of a composition.
     * 
     * @param c     A object of the type composition.
     * @param cl    A object of the type compositionLine.
     */
    private void modifyLine(Composition c, CompositionLine cl) {
        boolean change = inputDialog.inputBoolean("Rediger antal?");
        if(change) {
            int i = inputDialog.inputInt("Nyt antal: ");
            itemCtr.changeQuantity(cl, i);
        }
        else {
            boolean delete = inputDialog.inputBoolean("Slet produkt");
            if(delete) {
                itemCtr.deleteCompositionLine(c, cl);
            }
        }
    }

    /**
     * Method for printing a menu consisting of a compositions compositionlines and their products. 
     * 
     * @param c     A object of the type composition.
     */
    private MenuList<Integer> listCompLines(Composition c) {
        MenuList<Integer> m1 = new MenuList<Integer>("\fProdukter: " ,"\nVælg ");
        ArrayList<CompositionLine> cLines = c.getCompLines();
        for(int o = 0; o < cLines.size(); o++) {
            m1.addOption((o+1)+ "", "Produkt: " + cLines.get(o).getProduct().getName() +
                " Antal: " + cLines.get(o).getQuantity(), o+1);
        }
        m1.addOption((cLines.size()+1) + "", "Tilføj produkter", cLines.size()+1);
        m1.addOption("0", "Exit", 0);

        return m1;
    }

    /**
     * Method for setting the price on a product or composition.
     */
    private void setItemPrice() {
        try{
            int productID = inputDialog.inputInt("Indtast varenr.: ");
            Item i = itemCtr.retrieveItem(productID);
            if(i instanceof Product) {
                double salePrice = inputDialog.inputDouble("Indtast stk. pris: kr. ");
                double saleBulkPrice = inputDialog.inputDouble("Indtast kolli pris: kr. ");
                itemCtr.setProductPrice((Product)i, salePrice, saleBulkPrice);
            }
            else {
                double salePrice = inputDialog.inputDouble("Indtast pris: kr. ");
                itemCtr.setCompositionPrice((Composition)i, salePrice);
            }
        }
        catch(Exception e) {
            System.out.println(e);
        }
    }

    /**
     * Method for retrieving and printing information about a product or composition.
     */
    public void retrieveItem() {
        inputDialog.displayMessage("Find en vare: ");
        inputDialog.displayMessage("Du finder en vare ved at søge på dens ID.");
        try{
            Item item = itemCtr.retrieveItem(inputDialog.inputInt("Indtast varenr.: "));
            System.out.println("Varenavn: " + item.getName());
            System.out.println("Varebeskrivelse: " + item.getDescription());
            System.out.println("VareID: " + item.getID());
            System.out.println("Salgspris: " + item.getSalesPrice());
            if(item instanceof Product){
                Product p = (Product)item;
                System.out.println("Indkøbspris: " + p.getPurchasePrice());
                System.out.println("Antal i kolli: " + p.getQuantityInBulk());
                System.out.println("Kollipris: " + p.getSalesPriceBulk());
                System.out.println("Leverandør: " + p.getSupplier().getCompanyName());
                System.out.println("Størrelse: " + p.getSize());
                System.out.println("Vægt: " + p.getWeight());
            }
            else {
                Composition comp = (Composition)item;
                ArrayList<CompositionLine> compLines = comp.getCompLines();
                for(CompositionLine cl: compLines) {
                    System.out.println("Varenavn: " + cl.getProduct().getName() + " VareID: " + cl.getProduct().getID() + " Antal: " + cl.getQuantity());
                }
            }
            inputDialog.inputWait();
        }
        catch (Exception e){
            System.out.println(e);
            inputDialog.inputWait();
        }
    }

    /**
     * Method for deleting a item from our collections. 
     */
    public void deleteItem() {
        inputDialog.displayMessage("Du har valgt at slettet en vare: ");
        int  id = inputDialog.inputInt("Indtast varenr.: ");
        try {
            System.out.println("Navnet på varen du vil slette: " + itemCtr.retrieveItem(id).getName());
            if (inputDialog.inputBoolean("Er du sikker på at du vil slette denne vare?: ")) {
                itemCtr.deleteItem(id);
            }
        }
        catch (Exception e){
            System.out.println(e);
            inputDialog.inputWait();
        }
    }
}